package com.example.demo.service.Impl;

import com.example.demo.dto.FliterExamCondition;
import com.example.demo.entity.Application;
import com.example.demo.entity.Exam;
import com.example.demo.entity.Progress;
import com.example.demo.mapper.ApplicationMapper;
import com.example.demo.mapper.ExamMapper;
import com.example.demo.mapper.ProgressMapper;
import com.example.demo.service.ExamService;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
@RequiredArgsConstructor
@Transactional
public class ExamImpl implements ExamService {

    private final ExamMapper examMapper;
    private final ApplicationMapper applicationMapper;
    private final ApplicationImpl applicationImpl;
    private final ProgressImpl progressImpl;
    private final ProgressMapper progressMapper;
    @Override
    public Exam findExam(Long examId) {
        return examMapper.findById(examId);
    }

    @Override
    public List<Exam> filterExam(FliterExamCondition fliterExamCondition){
        return examMapper.filterExam(fliterExamCondition.getStudentName(),
                fliterExamCondition.getIdentityId(),
                fliterExamCondition.getLicenceId(),
                fliterExamCondition.getSubjectId(),
                fliterExamCondition.getExamTime());
    }

    @Override
    public Exam updateScore(String score,Long eid) {

//        Date date = new Date();
//        UpdateWrapper updateWrapper = new UpdateWrapper<>();
//        updateWrapper.eq("exam_id",eid);
//        updateWrapper.set("exam_score",score);
//        updateWrapper.set("exam_time",date);
        try{
            examMapper.updateScore(eid,score);
            progressImpl.updateByScore(score,eid);
            return examMapper.findById(eid);
        }
        catch (Exception e){
            throw new RuntimeException("Failed to update ExamScore");
        }
    }

    @Override
    public List<Exam> findAllExam(){
        return examMapper.findAll();
    }
    @Override
    public List<Exam> findByStudentID(Long studentId) {
//        QueryWrapper queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("student_id",studentId);
//        List<Exam> exams = examMapper.selectList(queryWrapper);
        return examMapper.findByStudentId(studentId);
    }
    @Override
    public List<Exam> findByCoachID(Long coachId){
        List<Exam> result = new ArrayList<>();
        List<Application> list = applicationMapper.findByCoachId(coachId);
        List<Exam> exams = examMapper.findAll();
        for (int i = 0;i<list.size();i++)
        {
            Long studentId = list.get(i).getStudentId();
            Long licenceId = list.get(i).getLicenceId();

            for (int j=0;j<exams.size();j++) {
                Long stuID=exams.get(j).getStudentId();
                Long licID=exams.get(j).getLicenceId();
                if(stuID==studentId&&licID==licenceId){
                    result.add(exams.get(j));
                }
            }
        }
        return result;
    }

    @Override
    public Exam findNewExam(Long studentId){
        List<Exam> exams = findByStudentID(studentId);
        exams.sort((t1, t2) -> t2.getExamTime().compareTo(t1.getExamTime()));
        return exams.get(0);
    }

    @Override
    public Exam addExam(Exam exam) {
        try {
            examMapper.insertExam(exam.getExamId(),exam.getLicenceId(),exam.getStudentId(),
                    exam.getSubjectId(),exam.getAppTime(),exam.getExamTime(),exam.getExamScore());
            Progress p = progressMapper.findProgressByApplicationId(
                    applicationImpl.findApplication(exam.getStudentId()).getApplicationId());
            progressMapper.updateProgress(p.getProgressId(),p.getApplicationId(),p.getSubjectId(),"已报名");
            return exam;
        }catch (Exception e){
            throw new RuntimeException("Failed to add Exam");
        }
    }

    @Override
    public Long deleteExam(Long examId) {
        int result = examMapper.deleteById(examId);
        if(result>0){
            return examId;
        }
        else {
            throw new RuntimeException("Failed to delete Exam");
        }
    }

    @Override
    public Exam updateExam(Exam exam) {
        try {
            examMapper.updateExam(exam.getExamId(),exam.getLicenceId(),exam.getStudentId(),
                    exam.getSubjectId(),exam.getAppTime(),exam.getExamTime(),exam.getExamScore());
            return exam;
        }catch (Exception e){
            throw new RuntimeException("Failed to update Exam");
        }
    }
}
